/**
 * 
 */
package edu.columbia.at2337.client;

import java.util.ArrayList;
import java.util.List;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HorizontalSplitPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.MenuBar;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

/**
 * @author Alvin Ting at2337@columbia.edu
 *
 */
public class AlvinHangmanModule implements EntryPoint {

	public static int MAX_GUESSES_INCORRECT = 6;
	public static String TEXT_GUESS = "Guesses remaining: ";
	
	private WordManager mWordManager = null;
	private int mGuessesWrong   = 0;
	private int mGuessesCorrect = 0;
	private String mSecretWord = "apple";
	
	// GUI
	FlowPanel mWordPanel = null;
	private Label mGuessText = null;
	private List<Button> mSecretWordList = null;
	private List<Button> mAlphabetList = null;
	
	// Commands
	Command mCmdDefault = null;
	Command mCmdNewGame = null;
	Command mCmdInstructions = null;
	Command mCmdHelp = null;
	
	public AlvinHangmanModule() {
		
		mWordManager = new WordManager();
		
		mAlphabetList = new ArrayList<Button>();
		
		// GUI
	    mWordPanel = new FlowPanel();
	    mWordPanel.setSize("390px", "60px");
		
		// Commands
		buildCommands();
		
		// Start a new game
		mCmdNewGame.execute();
	}
	
	/**
	 * Enable or disable the alphabet
	 */
	private void setEnabledAlphabet(boolean enable) {

		for (Button button : mAlphabetList) {
			button.setEnabled(enable);
		}

	}
	
	private void revealSecretWord() {
		
		String text = null;
		int index = 0;
		for (Button button : mSecretWordList) {
			text = button.getText();
			if (text.equals("_")) {
				button.setText(mSecretWord.substring(index, index+1));	
			}
			index++;

		}

	}

	
	public void buildCommands() {
		
		mCmdDefault = new Command() {
	      public void execute() {
	        Window.alert("Unimplemented");
	      }
	    };
	    
		mCmdNewGame = new Command() {
		      public void execute() {
		  		mSecretWord     = mWordManager.generateNewSecretWord();
				mSecretWordList = new ArrayList<Button>(mSecretWord.length());
				mGuessesCorrect = 0;
				mGuessesWrong   = 0;
				
				mWordPanel.clear();
				
				Button hiddenCharacter = null;
				for (int index=0; index<mSecretWord.length(); index++) {
					hiddenCharacter = new Button("_");
					hiddenCharacter.setSize("30px", "30px");
					hiddenCharacter.setEnabled(true);
					mWordPanel.add(hiddenCharacter );
					mSecretWordList.add(hiddenCharacter);
				}
				
				// Reset the alphabet
				setEnabledAlphabet(true);
				
		      }
		};
		
		
		mCmdInstructions = new Command() {
		      public void execute() {
			        Window.alert("These are the instructions.");
		      }
		};
		
		mCmdHelp = new Command() {
		      public void execute() {
			        Window.alert("This is the help menu.");
		      }
		};
	}
	
	
	public void onModuleLoad() {




		HorizontalSplitPanel mainPanel = new HorizontalSplitPanel();
		mainPanel.setSplitPosition("410px");

		


	    // Make some sub-menus that we will cascade from the top menu.
	    MenuBar mainMenu = new MenuBar(true);
	    mainMenu.addItem("New Game", mCmdNewGame);
	    mainMenu.addItem("Exit", mCmdDefault);

	    MenuBar helpMenu = new MenuBar(true);
	    helpMenu.addItem("Instructions", mCmdInstructions);
	    helpMenu.addItem("About", mCmdHelp);

	    // Make a new menu bar, adding a few cascading menus to it.
	    MenuBar menu = new MenuBar();
	    menu.addItem("File", mainMenu);
	    menu.addItem("Help", helpMenu);

	    // Add the menu bar to the main panel
	    RootPanel.get().add(menu);
	    
	    // Left side of the panel
		VerticalPanel leftPanel = new VerticalPanel();
		leftPanel.setSize("390px", "180px");
		leftPanel.setSpacing(10);
	
	    
	    // Guesses Panel ///////////////////////////////////////////////////////
	    FlowPanel guessPanel = new FlowPanel();
	    
	    mGuessText = new Label(TEXT_GUESS + MAX_GUESSES_INCORRECT);
	    
	    guessPanel.add(mGuessText);
	    leftPanel.add(guessPanel);
	    	    
	    // Secret word Panel ///////////////////////////////////////////////////
		
		// Add the word panel
		leftPanel.add(mWordPanel);
		
		// Alphabet panel //////////////////////////////////////////////////////
		FlowPanel alphabetPanel = new FlowPanel();
		alphabetPanel.setSize("390px", "60px");

		Button button = null;
		
		for (Character currLetter='a'; currLetter <= 'z'; currLetter++) {
			final String letter = currLetter.toString();
			button = new Button(letter);
			mAlphabetList.add(button);
			button.setSize("30px", "30px");
			button.addClickListener(new ClickListener()  {
				public void onClick(Widget arg0) {
					List<Integer> list = mWordManager.getOccurenceOf(letter);

					if (null != list) {
						Button hiddenCharacter = null;
						for (Integer number : list) {
							hiddenCharacter = mSecretWordList.get(number);
							hiddenCharacter.setText(letter);
							mGuessesCorrect++;
						}
						
						if (mGuessesCorrect == mSecretWord.length()) {
							System.err.println("You win!");
							
							// Disable the alphabet
							setEnabledAlphabet(false);
						}
						
					} else {
						System.err.println("Wrong guess");
						mGuessesWrong++;
						mGuessText.setText(TEXT_GUESS + 
								(MAX_GUESSES_INCORRECT - mGuessesWrong));
						
						if (mGuessesWrong >= MAX_GUESSES_INCORRECT) {
							System.err.println("You lose!");
							
							// Disable the alphabet
							setEnabledAlphabet(false);
							
							// Show word
							revealSecretWord();
						}
					}
					
					
					Button temp = (Button)arg0;
					temp.setEnabled(false);
				}
			});
			alphabetPanel.add(button);
		}
		
		// Add the alphabet panel
		leftPanel.add(alphabetPanel);
		
		// Info panel //////////////////////////////////////////////////////////
		FlowPanel infoPanel = new FlowPanel();
		infoPanel.setSize("390px", "60px");
	    
		// TODO
	    Label infoText = new Label("Playing");
	    
	    infoPanel.add(infoText);
	    leftPanel.add(infoPanel);


		////////////////////////////////////////////////////////////////////////
		mainPanel.setLeftWidget(leftPanel);
		
		FlowPanel rightPanel = new FlowPanel();
		Image hangman = new Image();
		hangman.setUrl(".\\hangman0.png");
		rightPanel.add(hangman);
		
		mainPanel.setRightWidget(rightPanel);
		
		RootPanel.get().add(mainPanel);
	}

}
